package ranab.jar.view;

import java.util.Vector;
import java.util.Date;
import java.util.Collections;
import java.util.zip.ZipEntry;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import ranab.gui.GuiUtils;
import ranab.jar.*;

/**
 * This is the table model to display Jar file.
 * 
 * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
 */
public 
class JarTable extends AbstractTableModel
               implements JarObserver, JarUI {

    private final static SimpleDateFormat mFormatter = new SimpleDateFormat ("dd,MMM,yy HH:mm");

    public final static ZipComparator[] mHeader = {
        new ZipNameComparator(), 
        new ZipSizeComparator(), 
        new ZipCompressedSizeComparator(), 
        new ZipModificationTimeComparator(), 
        new ZipPathComparator()
    };


    private Vector mTabelData = null;

    private Component mParent;
    private JTable mjTable;
    
    private JPanel mjTopPane;
    private JComboBox mjAscCombo;
    private JComboBox mjDesCombo;
    
    private boolean mbIsActive;
    
    
    /**
     * Initialize the table model
     */
    public JarTable(Component parent) {
        mTabelData = new Vector();
        mParent = parent;
        mbIsActive = false;
        initComponents();
    }

    /**
     * Init UI components
     */
    private void initComponents()  {
        mjTable = new JTable(this);
        mjTable.setColumnSelectionAllowed(false);
        mjTable.setBackground(Color.white);
        
        JScrollPane scrollPane = new JScrollPane(mjTable, 
                                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                                       JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        mjTopPane = new JPanel();
        mjTopPane.setLayout(new BorderLayout());
        mjTopPane.add(scrollPane, BorderLayout.CENTER);
        mjTopPane.add(getComboPanel(), BorderLayout.NORTH);
    }
    
    /**
     * Create sort combo panel.
     */
    private JPanel getComboPanel()  {
    
        JPanel ascPanel = new JPanel();
        JLabel ascLabel = new JLabel("Ascending Sorting");
        ascLabel.setForeground (Color.black);
        ascLabel.setHorizontalAlignment (SwingConstants.CENTER);
        ascLabel.setFont (new Font ("Serif", 1, 14));
        mjAscCombo = new JComboBox(JarTable.mHeader);
        mjAscCombo.addActionListener(
            new ActionListener()  {
                public void actionPerformed(ActionEvent e)  {
                    ZipComparator comp = (ZipComparator)mjAscCombo.getSelectedItem();
                    sortColumn(comp, true);
                }
            }
        );
        ascPanel.add(ascLabel);
        ascPanel.add(mjAscCombo);
        
        JPanel desPanel = new JPanel();
        JLabel desLabel = new JLabel("Descending Sorting");
        desLabel.setForeground (Color.black);
        desLabel.setHorizontalAlignment (SwingConstants.CENTER);
        desLabel.setFont (new Font ("Serif", 1, 14));
        mjDesCombo = new JComboBox(JarTable.mHeader);
        mjDesCombo.addActionListener(
            new ActionListener()  {
                public void actionPerformed(ActionEvent e)  {
                    ZipComparator comp = (ZipComparator)mjDesCombo.getSelectedItem();
                    sortColumn(comp, false);
                }
            }
        );
        desPanel.add(desLabel);
        desPanel.add(mjDesCombo);
        
        JPanel topPane = new JPanel();
        topPane.setLayout(new FlowLayout(FlowLayout.CENTER));
        topPane.add(ascPanel);
        topPane.add(desPanel);
        return topPane;
    }
    
    
    // TableModel implementation
    /**
     * Get the number of columns.
     */
    public int getColumnCount() {
        return mHeader.length;
    }

    /**
     * Get column name.
     */
    public String getColumnName(int index) {
        return mHeader[index].getHeaderName();
    }

    /**
     * Get column class.
     */
    public Class getColumnClass(int columnIndex) {
        switch (columnIndex) {
        case 0:
            return String.class;

        case 1:
            return Long.class;

        case 2:
            return Long.class;

        case 3:
            return String.class;

        case 4:
            return String.class;

        default:
            return String.class;
        }
    }

    /**
     * Cell is not editable in this table.
     */
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    /**
     * Get the number of rows.
     */
    public int getRowCount() {
        return mTabelData.size();
    }

    /**
     * Get cell value.
     */
    public Object getValueAt(int rowIndex, int columnIndex) {
        ZipEntry ze = (ZipEntry)mTabelData.elementAt(rowIndex);
        switch (columnIndex) {
        case 0: 
            return ZipNameComparator.getName(ze);

        case 1:
            return new Long(ze.getSize());

        case 2:
            return new Long(ze.getCompressedSize());

        case 3:
            return mFormatter.format(new Date(ze.getTime()));

        case 4:
            return ZipPathComparator.getPath(ze);

        default:
            return null;
        }
    }

    // MyJarObserver implementation
    /**
     * Start viewing - clear the old data
     */
    public void start() {
        int sz = mTabelData.size();
        if (sz != 0) {
            mTabelData.clear();
            fireTableRowsDeleted(0, sz-1);
        }
    }

    /**
     * Set count - ignore.
     */
    public void setCount(int count) {
    }

    /**
     * Next entry found.
     */
    public void setNext(ZipEntry je) {
        int row = mTabelData.size();
        if (!je.isDirectory()) {
            mTabelData.add(je);
            fireTableRowsInserted(row, row);
        }
    }

    /**
     * Error messgae.
     */
    public void setError(String errMsg) {
        if (isActive())  {
            GuiUtils.showErrorMessage(mParent, errMsg);
        }
    }  

    /**
     * End viewing - ignore.
     */
    public void end() {
    }

    /**
     * Update component UI.
     */
    public void updateLnF() {
        SwingUtilities.updateComponentTreeUI(mjTopPane);
    }
    
    /**
     * Get the scroll pane that contains the table.
     */
    public JPanel getPanel() {
        return mjTopPane;
    }
    
    
    /**
     * Is active
     */
    public boolean isActive()  {
        return mbIsActive;
    }
    
    /**
     * Set enable tag.
     */
    public void setActive(boolean b)  {
        mbIsActive = b;
    }
    
    /**
     * Returns the selected zip entries.
     */
    public ZipEntry[] getSelectedEntries() {
        int indices[] = mjTable.getSelectedRows();
        if (indices.length == 0) {
            return null;
        }

        ZipEntry entries[] = new ZipEntry[indices.length];
        for (int i=0; i<entries.length; i++) {
            entries[i] = (ZipEntry)mTabelData.elementAt(indices[i]);
        }
        return entries;
    }
    
    /**
     * Sort column.
     */
    public void sortColumn(ZipComparator comp, boolean asc)  {

        if (comp == null) {
            return;
        }

        ZipComparator finalComp = null;
        if (asc) {
            finalComp = comp;
        } else {
            finalComp = new ZipReverseComparator(comp);
        }
        Collections.sort(mTabelData, finalComp);
        fireTableDataChanged();
    }

} 
